package com.mentaleye.shiro.realm;

import com.mentaleye.bean.UserLoginBean;
import com.mentaleye.service.UserLoginService;
import com.mentaleye.shiro.Constants;
import com.mentaleye.shiro.RedisCache;
import com.mentaleye.shiro.RedisKeyEnum;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

public class CustomRealm extends AuthorizingRealm implements Realm, InitializingBean {

	@Autowired
	private RedisCache<String, Object> redisCache;

	@Autowired
	private UserLoginService loginService;

	public CustomRealm() {
	}

	@SuppressWarnings("unchecked")
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Set<String> roleStringSet = null;
		Set<String> permStringSet = null;
		List<Map<String, Object>> loginList = null;
		Map<String, Object> map = new HashMap<String, Object>();
		String loginName = (String) super.getAvailablePrincipal(principals);
		// 去缓存中查询 角色和权限;
		roleStringSet = (Set<String>) redisCache.get(Constants.getRedisKey(RedisKeyEnum.USER_ROLES, loginName));
		permStringSet = (Set<String>) redisCache.get(Constants.getRedisKey(RedisKeyEnum.USER_PERMS, loginName));
		// 缓存为空去数据库中查询
		if (roleStringSet == null || permStringSet == null) {
			roleStringSet = new HashSet<String>();
			permStringSet = new HashSet<String>();

			map.put("loginName", loginName);
			loginList = this.loginService.getLoginByMap(map);
			for (Map<String, Object> loginMap : loginList) {
				roleStringSet.add(loginMap.get("role_id").toString());
				permStringSet.add(loginMap.get("perm_id").toString());
			}
			redisCache.put(Constants.getRedisKey(RedisKeyEnum.USER_ROLES, loginName), roleStringSet);
			redisCache.put(Constants.getRedisKey(RedisKeyEnum.USER_PERMS, loginName), permStringSet);
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setRoles(roleStringSet);
		info.setStringPermissions(permStringSet);
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String loginName = upToken.getUsername();
		UserLoginBean loginBean = (UserLoginBean) this.redisCache.get(Constants.getRedisKey(RedisKeyEnum.USER_LOGIN, loginName));
		// PasswordHelper.encryptPassword(userLogin);
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(loginBean.getLoginName(), loginBean.getPassword(),
				ByteSource.Util.bytes(loginBean.getCredentialsSalt()), super.getName());
		redisCache.put(Constants.getRedisKey(RedisKeyEnum.USER_SESSION, loginName), loginBean);
		return info;

	}

	/**
	 * 更新用户授权信息缓存.
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
		super.clearCachedAuthorizationInfo(principals);
		super.clearCache(principals);
		super.clearCachedAuthenticationInfo(principals);
		redisCache.remove("UserLoginBean");
		redisCache.remove(Constants.getRedisKey(RedisKeyEnum.USER_PERMS, principal));
		redisCache.remove(Constants.getRedisKey(RedisKeyEnum.USER_ROLES, principal));
		redisCache.remove(Constants.getRedisKey(RedisKeyEnum.USER_SESSION, principal));
	}

	/**
	 * 清除所有用户授权信息缓存.
	 */
	public void clearAllCachedAuthorizationInfo() {
		redisCache.clear();
	}

	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub

	}

}